using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using dnAnalytics.Math;
using dnAnalytics.LinearAlgebra;
using dnAnalytics.LinearAlgebra.Decomposition;
using dnAnalytics.LinearAlgebra.IO;
using dnAnalytics.Exceptions;

namespace dnAnalytics.UnitTests.LinearAlgebra.Decomposition
{
    public class DenseLUTest : AbstractLUTest
    {
        public override Matrix GetMatrix(int rows, int columns)
        {
            return MatrixBuilder.CreateMatrix(rows, columns, MatrixType.Dense);
        }

        public override Matrix GetMatrix(int order)
        {
            return MatrixBuilder.CreateMatrix(order, MatrixType.Dense);
        }

        public override void GetDecompositionClass(String file, out Matrix matrix, out LU lu)
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            matrix = mmr.ReadMatrix(file, MatrixType.Dense);
            lu = new LU(matrix);
        }

        public override Vector GetVector(int size)
        {
            return VectorBuilder.CreateVector(size, VectorType.Dense);
        }
    }

    [TestFixture]
    [Category("Managed")]
    [Category("Dense")]
    public class ManagedDenseLUTest : DenseLUTest
    {
        static ManagedDenseLUTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = false;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Dense;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Dense;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("Mkl")]
    [Category("Dense")]
    public class MklDenseLUTest : DenseLUTest
    {
        static MklDenseLUTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Mkl;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.Mkl;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Dense;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Dense;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("Acml")]
    [Category("Dense")]
    public class AcmlDenseLUTest : DenseLUTest
    {
        static AcmlDenseLUTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Acml;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.Acml;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Dense;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Dense;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("Atlas")]
    [Category("Dense")]
    public class AtlasClapackDenseLUTest : DenseLUTest
    {
        static AtlasClapackDenseLUTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Atlas;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.Clapack;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Dense;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Dense;
        }
    }

    [TestFixture]
    [Category("Managed")]
    [Category("Dense")]
    public class ManagedSparseDenseLUTest : DenseLUTest
    {
        static ManagedSparseDenseLUTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = false;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Sparse;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Sparse;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("Mkl")]
    [Category("Dense")]
    public class MklSparseDenseLUTest : DenseLUTest
    {
        static MklSparseDenseLUTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Mkl;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.Mkl;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Sparse;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Sparse;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("Acml")]
    [Category("Dense")]
    public class AcmlSparseDenseLUTest : DenseLUTest
    {
        static AcmlSparseDenseLUTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Acml;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.Acml;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Sparse;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Sparse;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("Atlas")]
    [Category("Dense")]
    public class AtlasClapackSparseDenseLUTest : DenseLUTest
    {
        static AtlasClapackSparseDenseLUTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Atlas;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.Clapack;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Sparse;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Sparse;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("AcmlIFort")]
    [Category("Dense")]
    public class AcmlIFortDenseDenseLUTest : DenseMatrixTest
    {
        static AcmlIFortDenseDenseLUTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Acml;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.AcmlIFort;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Dense;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Dense;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("AcmlIFort")]
    [Category("Dense")]
    public class AcmlIFortSparseDenseDenseLUTest : DenseMatrixTest
    {
        static AcmlIFortSparseDenseDenseLUTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Acml;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.AcmlIFort;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Sparse;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Sparse;
        }
    }
}
